#include <iostream>

#include <iostream>
#include <unistd.h>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "log.hpp"
#include "Inetaddr.hpp"

int main(int argc, char* argv[])
{
    if (argc != 3)
    {
        std::cerr << "Usage: " << argv[0] << " server-ip server-port" << std::endl;
        exit(1);
    } 

    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    int socketfd = ::socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd < 0)
    {
        std::cerr << "create socket error!\n" << std::endl;
        exit(1);
    }
    
    // 即使是TCP，客户端通信的时候，
    // 仍然不需要 "显式"将 套接字 和 服务器的IP与服务器确定好的 端口进行绑定，
    // 因为操作系统会在 连接发起时，将这两者绑定

    // 在TCP协议中，客户端需要向服务器发起连接
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(serverport);

    ::inet_pton(AF_INET, serverip.c_str(), (struct sockaddr*)&server.sin_addr);
    int n = ::connect(socketfd, (struct sockaddr*)&server, sizeof(server));
    if (n < 0)
    {
        std::cerr << "connect socket error" << std::endl;
        exit(2);
    }
    
    while (true)
    {
        std::string message;
        std::cout << "Enter# ";
        std::getline(std::cin, message);
        write(socketfd, message.c_str(), message.size());

        char echo_buffer[1024];
        int m = read(socketfd, echo_buffer, sizeof(echo_buffer));
        if (m > 0)
        {
            echo_buffer[m] = 0;
            std::cout << echo_buffer << std::endl;
        }
        else
        {
            break;
        }
    }
    ::close(socketfd);
    
    return 0;
}
